#!/usr/bin/python
# -*- coding: utf8 -*-

import gtk
import gobject

from gui.helpers import WidgetsWrapper
from gui.config import *

from lenguaje import Lenguaje
from registro import extensiones


class MainHandler:
    # --------------------------------------------- #
    # Handlers para la ventana de "Acerca de..."    #
    # --------------------------------------------- #
    
    def on_acerca_de_activate(event):
        class AboutHandlers:
            def on_acerca_de_close(event):
                about[ABOUT_WINDOW].hide()
            def on_acerca_de_response(id, event):
                about[ABOUT_WINDOW].hide()

        about = WidgetsWrapper(ABOUT_WINDOW, AboutHandlers)
        
        # Esto por alguna razon no se setea bien en el Glade,
        # así que lo seteo de nuevo manualmente acá.
        about[ABOUT_WINDOW].set_program_name(PROGRAM_NAME)


    #----------------------------------------------#
    # Handlers para los botones de comando         #
    #----------------------------------------------#

    def on_boton_sintaxis_clicked(event):
        s = get_input()
        lang = get_lenguaje()
        try:
            exp = lang.parseString(s)
            set_output("Sintaxis correcta!")
        except Exception, e:
            set_output(str(e))

    def on_boton_tipos_clicked(event):
        s = get_input()
        lang = get_lenguaje()
        try:
            exp = lang.parseString(s)
            tipo = exp.tipar({})
            set_output(str(tipo))
        except Exception, e:
            set_output(str(e))

    def on_boton_evaluar_clicked(event):
        s = get_input()
        lang = get_lenguaje()
        try:
            exp = lang.parseString(s)
            tipo = exp.tipar({})
            res = exp.reducir()
            set_output(str(res))
        except Exception, e:
            set_output(str(e))

    #----------------------------------------------#
    # Handlers para abrir/guardar                  #
    #----------------------------------------------#

    def archivo_abrir_clicked(event):
        abrir = WidgetsWrapper(ABRIR_WINDOW)
        wnd = abrir[ABRIR_WINDOW]
        wnd.hide()
        res = wnd.run()
        wnd.hide()
        if res == gtk.RESPONSE_OK:
            fname = wnd.get_filename()

            try:
                fi = open(fname, 'rb')
            except Exception, e:
                mostrar_error("Error al cargar", str(e))
                return

            widgets[INPUT].get_buffer().set_text(fi.read())
           
            global archivo_abierto
            archivo_abierto = fname
            widgets[MENU_GUARDAR].set_sensitive(True)
            
        elif res == gtk.RESPONSE_CANCEL or \
             res == gtk.RESPONSE_DELETE_EVENT:
            return
        else:
            raise ValueError("Respuesta no esperada al dialogo de abrir!")


    def archivo_guardar_clicked(event):
        global archivo_abierto
        if archivo_abierto is None:
            return
        else:
            fname = archivo_abierto

        try:
            fw = open(fname, 'wb')
            fw.write(get_input())
        except Exception, e:
            mostrar_error("Error al guardar", str(e))


    def archivo_guardar_como_clicked(event):
        guardar = WidgetsWrapper(GUARDAR_WINDOW)
        wnd = guardar[GUARDAR_WINDOW]
        wnd.hide()
        res = wnd.run()
        wnd.hide()

        if res == gtk.RESPONSE_OK:
            fname = wnd.get_filename()
            if not fname.endswith('.lc'):
                fname += '.lc'

            try:
                fw = open(fname, 'wb')
                fw.write(get_input())
            except Exception, e:
                mostrar_error("Error al guardar", str(e))
                return

            global archivo_abierto
            archivo_abierto = fname
            widgets[MENU_GUARDAR].set_sensitive(True)
 
 
        elif res == gtk.RESPONSE_CANCEL or \
             res == gtk.RESPONSE_DELETE_EVENT:
            return
        else:
            raise ValueError("Respuesta no esperada al dialogo de guardar!")



    #----------------------------------------------#
    # Handlers para salir del programa             #
    #----------------------------------------------#

    def on_main_window_delete_event(widget, event):
        gtk.main_quit()

    def on_salir_activate(event):
        gtk.main_quit()




#---------------------------------------------------------#
# Funciones para manipular la habilitación de extensiones #
#---------------------------------------------------------#

def cargar_extensiones(exts):
    ls = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN, gobject.TYPE_PYOBJECT)
    tv = widgets[LISTA_EXTENSIONES]
    tv.set_model(ls)

    # Agrego la columna para los nombres
    tv.append_column(gtk.TreeViewColumn('Nombre', gtk.CellRendererText(), text=0))

    # Agrego la columna para los estados de activación
    rend_toggle = gtk.CellRendererToggle()
    rend_toggle.set_property('activatable', True)
    
    def toggle_ext(cell, path, model):
        model[path][1] = not model[path][1]

    rend_toggle.connect('toggled', toggle_ext, ls)
    col_toggle = gtk.TreeViewColumn(None, rend_toggle)
    col_toggle.add_attribute(rend_toggle, "active", 1)
    tv.append_column(col_toggle)

    # Cargo las extensiones posibles
    for e in exts:
        it = ls.insert(100)
        ls.set_value(it, 0, e.nombre)
        ls.set_value(it, 1, True)
        ls.set_value(it, 2, e)


def get_lenguaje():
    tv = widgets[LISTA_EXTENSIONES]
    ls = tv.get_model()
    return Lenguaje([e[2] for e in ls if e[1]])



#---------------------------------#
# Funciones para I/O del programa #
#---------------------------------#

def get_input():
    buf = widgets[INPUT].get_buffer()
    begin = buf.get_start_iter()
    end = buf.get_end_iter()
    return buf.get_text(begin, end)

def set_output(s):
    buf = widgets[OUTPUT].get_buffer()
    buf.set_text(s)



#---------------------------------#
# Helpers misc.                   #
#---------------------------------#

def mostrar_error(titulo, texto):
    error = WidgetsWrapper(ERROR_WINDOW)
    wnd = error[ERROR_WINDOW]
    wnd.hide()
    error[ERROR_MSG].set_markup("<b>%s</b>\n%s" % (titulo, texto))
    wnd.run()
    wnd.destroy()



#------#
# Main #
#------#

if __name__ == '__main__':
    
    global widgets
    global archivo_abierto
    archivo_abierto = None

    # Aumento el limite de recursión para evitar problemas
    # de stack overflow en el intérprete.
    import sys
    sys.setrecursionlimit(5000)

    widgets = WidgetsWrapper(MAIN_WINDOW, MainHandler)
    cargar_extensiones(extensiones)

    gtk.main()
